/*************************************************
*      Filename: main_text.cu
*        Coding: utf-8
*        Author: Zheng Li
*         Email: lizheng@galasports.net
*      HomePage: http://www.galasports.net
*  Copyright(C): InnoReal Technology Co.,Ltd.
*       Version: 0.0.1
*    CreateDate: 2018-07-20 20:26:39
*    LastChange: 2018-07-20 20:28:53
*          Desc: 
*       History: 
*************************************************/
#include <innoreal/utils/innoreal_helper.hpp>
#include <innoreal/utils/innoreal_timer.hpp>
#include "input_data.h"
#include "constant.h"
#include "gn_solver.h"
#include "distance_twomesh.h"
#include "keyframe_find.h"
#include "keyframe_movingpoint.h"
#include <vector>
#include "output_vector1d2d.h"
#include "output_vec1d2d_typename.h"
#include <vector_functions.hpp>
class MeshVertex{
 public:
  int num_vertex_;
  std::vector<float4> d_vertex_;
};
class TwoMesh{
 public:
  MeshVertex source_;
  MeshVertex target_;
};

void ReadDataFromFile(std::string file, MeshVertex *data) {
  std::ifstream mesh_fn(file);

  std::vector<float4> h_vertex;
  h_vertex.reserve(200000);

  float x, y, z;
  char flag;
  std::string line;
  while (std::getline(mesh_fn, line)) {
    if (line.find('t') != -1) {
      printf("wrong line find t\n!");
    } else {
      sscanf(line.c_str(), "%c %f %f %f", &flag, &x, &y, &z);
    }
    if ('v' == flag) {
      h_vertex.push_back(make_float4(x,y,z,0.f));
    }
  }
  mesh_fn.close();

  data->num_vertex_ = h_vertex.size();
  data->d_vertex_ = h_vertex;
}

void FormulateTwoData(std::string src, std::string tar, TwoMesh *data){
  ReadDataFromFile(src, &data->source_);
  ReadDataFromFile(tar, &data->target_);
}

double Hausdorff_Simple(TwoMesh *data)
{
  double distance = 0.0;
  thrust::host_vector<float4> v_a = data->source_.d_vertex_;
  thrust::host_vector<float4> v_b = data->target_.d_vertex_;
  int va_N = data->source_.num_vertex_;
  int vb_N = data->target_.num_vertex_;
  double dis_temp;
  double dis_temp1 = 0, dis_temp2;
  for(int i = 0; i < va_N; i++){
    dis_temp2 = 1000000;
    for(int j = 0; j < vb_N; j++){
      dis_temp = sqrt((v_a[i].x-v_b[j].x)*(v_a[i].x-v_b[j].x) + (v_a[i].y-v_b[j].y)*(v_a[i].y-v_b[j].y)  + (v_a[i].z-v_b[j].z)*(v_a[i].z-v_b[j].z));
      if(dis_temp<dis_temp2){
        dis_temp2=dis_temp;
      }
    }
    if(dis_temp2>dis_temp1){
      dis_temp1=dis_temp2;
    }
  }
  distance=dis_temp1;
  return distance;
}

int main(int argc, char** argv)
{

  KeyFrameFind *keyframe_find = new KeyFrameFind;
  KeyFrameMovingPoint * keyframe_movingpoint = new KeyFrameMovingPoint;
  TwoMesh *input_data=new TwoMesh;
  DisTwoMesh *distmesh = new DisTwoMesh;
  char file_src[100], file_tar[100], file_tar1[100], file_tar2[100];

  int N = atoi(argv[1]);
  int K = atoi(argv[2]);
  INNOREALI("Frame_sum: %d    Frame_given: %d \n", N, K);


  std::vector<int> center;//center.resize(K);
  std::vector<double> costL,costR;//ncenter.resize(K);
  std::vector<int> L,R;
  int c1=0,c2=0;
  double dis1=0,dis2=0,dis=0;
  int label[N];


  int spacing=N/K;
  for(int i=0;i<K;i++){
    center.push_back(i*spacing+1);
    costL.push_back(0);
    costR.push_back(0);
    L.push_back(0);
    R.push_back(0);
  }


//  for(int i=0;i<center[0];i++){
//    sprintf(file_src, "/data/workspace/Offline4D/data/168/mesh/mesh%d.obj", i);
//    sprintf(file_tar, "/data/workspace/Offline4D/data/168/mesh/mesh%d.obj", center[0]);
//    input_data->Init(file_src, file_tar);
//    dis = distmesh->Hausdorff_igl(input_data);
//    label[i]=1;
//    costL[0]+=dis;
//  }
//  L[0]=0;


  for(int i=center.back();i<N;i++){
    sprintf(file_src, "/data/workspace/Offline4D/data/168/mesh/mesh%d.obj", i);
    sprintf(file_tar, "/data/workspace/Offline4D/data/168/mesh/mesh%d.obj", center[0]);
    FormulateTwoData(file_src, file_tar, input_data);
    dis = Hausdorff_Simple(input_data);
    label[i]=K;
    costL[K-1]+=dis;
  }
  R[K-1]=N-1;


//  for(int i=0;i<K-1;i++){
//    INNOREALI("i: %d   %d \n", i, K);
//    c1=center[i];c2=center[i+1];
//    sprintf(file_tar1, "/data/workspace/Offline4D/data/168/mesh/mesh%d.obj", c1);
//    sprintf(file_tar2, "/data/workspace/Offline4D/data/168/mesh/mesh%d.obj", c2);
//    for(int j=c1;j<=c2;j++){
//      sprintf(file_src, "/data/workspace/Offline4D/data/168/mesh/mesh%d.obj", j);
//      input_data->Init(file_src, file_tar1);    input_data->GetIijSet();
//      dis1 = distmesh->Hausdorff_igl(input_data);
//      input_data->Init(file_src, file_tar2);    input_data->GetIijSet();
//      dis2 = distmesh->Hausdorff_igl(input_data);
//      if(dis1<dis2){
//        label[j]=i+1;
//        costR[i]=costR[i]+dis1;
//        R[i]=j;
//      }else{
//        label[j]=i+2;
//        costL[i+1]=costL[i+1]+dis2;
//        if(L[i+1]==0){
//          L[i+1]=j;
//        }
//      }
//    }
//  }
//
//  for(int i=0;i<K;i++){
//   center[i]=(L[i]+R[i])/2;
//  }


//  printf("Step1: Initialization .......\n");
//  Calculate_Total_Evalation *calculate_total_evalation = new Calculate_Total_Evalation;
//  //关键帧初始化，keyframe
//  for(int iter_out = 0; iter_out < sourceframe_Num; iter_out++) {
//    //d
//    if( (iter_out%((sourceframe_Num+1)/givenframe_Num) == ((sourceframe_Num+1)/givenframe_Num)-1) && keyframe.size() < givenframe_Num)
//      keyframe.push_back(iter_out);
//  }


//  Output_Vector output_vector;
//  output_vector.Vec1dint_Output(keyframe_movingpoint->keyframe);
//  output_vector.Vec2ddouble_Output(keyframe_movingpoint->diseva);
//  output_vector.Keyframe_Output_File(keyframe_find->keyframe, Frame_sum, "test_keyframe.csv");


  delete keyframe_movingpoint;
  delete keyframe_find;
  return 0;


}

